home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright 1990 by Gary R. Olhoeft
- * This code may be freely copied for personal,
- * non-commercial use. compile using MicroWay's
- * NDP C-386 compiler:
- * cc graphics.c -w -v -rt2 -n2 -n3 -lGREX.LIB
- */
-
- #include <stdio.h>
- #include <dos.h>
- #include <grex.h>
-
- void plot_pixel();
- void graphics();
- void spectrum();
- void ext_palette();
-
- union REGS reg; /* required by inline assembly */
- int v_mode, v_color, v_rowy, v_colx, page;
- unsigned short ati_extreg;
- char ega_palette[17] = {0,1,9,11,3,19,2,18,6,54,38,
- 52,4,36,41,13,0};
- int modes[] = {0x0d,0x0e,0x10,0x12,0x13,0x54,
- 0x62,0x63,0x65};
- void main()
- {
- int i,x,y,key;
- unsigned char color;
- for (i=0; i<9; i++)
- {
- graphics(modes[i]); /* cycle through ATI VGA
- Wonder graphics modes */
- printf("Mode %d %dx%dx%d\n",v_mode,v_colx+1,
- v_rowy+1,v_color+1);
- /* printing shrinks as pixel count increases */
- spectrum();
- /* draw banded color lines on screen */
- for (x = 0; x<=v_colx>>2; x++)
- {
- for (y = 0; y<=v_rowy; y++)
- {
- color = y % v_color;
- plot_pixel(x+y,y,color);
- }
- }
- /* pause loop until keypress;
- exit with ^C or Esc */
- if ((key=pauseb())==27) {
- set_video_mode(0x02); exit();
- }
- }
- set_video_mode(0x02); /* restore text mode */
- exit();
- }
-
- void graphics(mode)
- unsigned char mode;
- {
- unsigned char buffer[2];
- switch (mode) /* note: not all possible modes shown */
- {
- case 0x0d: /* EGA */
- v_colx = 320;
- v_rowy = 200;
- v_color = 16;
- break;
- case 0x0e: /* EGA */
- v_colx = 640;
- v_rowy = 200;
- v_color = 16;
- break;
- case 0x10: /* EGA high resolution */
- v_colx = 640;
- v_rowy = 350;
- v_color = 16;
- break;
- case 0x12: /* VGA */
- v_colx = 640;
- v_rowy = 480;
- v_color = 16;
- break;
- case 0x13: /* MCGA */
- v_colx = 320;
- v_rowy = 200;
- v_color = 256;
- break;
- case 0x54: /* ATI SVGA */
- v_colx = 800;
- v_rowy = 600;
- v_color = 16;
- break;
- case 0x62: /* ATI SVGA */
- v_colx = 640;
- v_rowy = 480;
- v_color = 256;
- break;
- case 0x63: /* ATI SVGA */
- v_colx = 800;
- v_rowy = 600;
- v_color = 256;
- break;
- case 0x65: /* ATI SVGA */
- v_colx = 1024;
- v_rowy = 768;
- v_color = 16;
- break;
- default:
- mode = 0x02; /* text mode */
- v_colx = 80;
- v_rowy = 25;
- v_color = 1;
- break;
- }
- v_mode = mode;
- v_colx--; /* set ranges 0 to pixels-1 */
- v_rowy--;
- v_color--;
-
- reg.b.ah = 0;
- reg.b.al = mode;
- int386(0x10,®,®); /* call BIOS video
- interrupt to set mode */
-
- blk_mb(buffer, 0x34, 786448, 2);
- ati_extreg = buffer[0]+256*buffer[1];
- /* find ATI extended_reg address
- (could use peek() instead)*/
- page = 99; /* force paging first plot cycle */
- }
-
- /* plot pixel of color at (x,y) display units */
- void plot_pixel(x,y,color)
- int x,y;
- unsigned char color;
- {
- #define peek(addr, val) asm(" push es"); \
- asm(" mov ax, 034h"); asm(" mov \
- es, ax"); ebx = addr; asm(ebx, " mov \
- cl, byte ptr es:[ebx]", cl); val = cl; asm\
- (" pop es")
- #define poke(addr, val) asm(" push es"); \
- cl = val; asm(" mov ax, 034h"); \
- asm(" mov es, ax"); ebx = addr; \
- asm(ebx, cl, " mov byte ptr es:[ebx], \
- cl"); asm(" pop es")
- /* required by inline assembly */
- reg$eax unsigned short ax;
- reg$eax unsigned char al;
- reg$ah unsigned char ah;
- reg$ecx unsigned short cx;
- reg$ch unsigned char ch;
- reg$ecx unsigned char cl;
- reg$edx unsigned short dx;
- reg$edx unsigned char dl, val;
- reg$ebx unsigned ebx, addr;
- int i,vcol,yvx;
- if ((y < 0) || (y > v_rowy) || (x < 0) ||
- (x > v_colx)) return;
- /* clip physical display boundaries */
- y = v_rowy-y; /* put (0,0) at lower left corner of plotter */
- vcol = v_colx+1;
- yvx = y*vcol + x;
- switch (v_mode)
- {
- case 0x65: /* ATI 1024x768x16 */
- ch = (char)(y >> 6);
- if (ch!=page) /* only change page if different */
- {
- dx = ati_extreg; /* location of ATI card external register */
- asm(" cli "); /* disable interrupts */
- asm(" mov al,0b2h"); /* page select */
- asm(dx," out dx,al"); /* ATI extended register */
- asm(" inc dl");
- asm(" in al,dx");
- asm(" mov ah,al");
- asm(" and ah,0e1h"); /* page mask */
- asm(ch," or ah,ch"); /* ch = memory page desired */
- asm(" mov al,0b2h"); /* page select */
- asm(" dec dl");
- asm(" out dx,ax");
- asm(" sti "); /* enable interrupts */
- page = ch;
- }
- addr = 655360 + ((y << 9) % 65536) + (x >> 1);
- peek(addr, val); /* read existing color of pixel pair */
- if (x % 2) val = color | (val & 0xF0); /* change addressed pixel */
- else val = (color << 4) | (val & 0x0F);
- poke(addr, val); /* write pixel pair */
- break;
- case 0x13: /* MCGA 320x200x256 */
- addr = 655360 + yvx;
- poke(addr, color); /* write direct to real video memory */
- break;
- case 0x62: /* ATI 640x480x256 */
- case 0x63: /* ATI 800x600x256 */
- ch = (unsigned char)(yvx >> 15);
- if (ch!=page)
- {
- dx = ati_extreg; /* location of ATI card external register */
- asm(" cli "); /* disable interrupts */
- asm(" mov al,0b2h"); /* page select */
- asm(dx," out dx,al"); /* ATI extended register */
- asm(" inc dl");
- asm(" in al,dx");
- asm(" mov ah,al");
- asm(" and ah,0e1h"); /* page mask */
- asm(ch," or ah,ch"); /* ch = memory page desired */
- asm(" mov al,0b2h"); /* page select */
- asm(" dec dl");
- asm(" out dx,ax");
- asm(" sti "); /* enable interrupts */
- page = ch;
- }
- addr = 655360 + (yvx % 65536);
- poke(addr, color); /* write direct to real video memory */
- break;
- default:
- /* 0x10 EGA 640x350x16, 0x12 VGA 640x480x16, 0x54 ATI 800x600x16 */
- asm(" push es"); /* save segment register */
- asm(" mov ax, 034h"); /* use Phar Lap LDT to */
- asm(" mov es, ax"); /* access real memory */
- dx = 0x3ce; /* EGA graphics register */
- ebx= 655360 + (yvx >> 3); /* memory position of pixel */
- asm(ebx, " mov cl, byte ptr es:[ebx]"); /* load EGA registers */
- ax = color << 8;
- asm(dx, ax, " out dx, ax"); /* set color */
- ax = 0x0F01;
- asm(dx, ax, " out dx, ax"); /* enable */
- ax = 0x0003; /* 0x00 = replace, 0x10 OR, 0x18 XOR, 0x08 AND */
- asm(dx, ax, " out dx, ax"); /* pixel write mode */
- ax = ((0x80 >> (x%8)) << 8 ) + 8;
- asm(dx, ax, " out dx, ax"); /* bit mask (8 pixels/byte) */
- asm(ebx, " mov byte ptr es:[ebx], 255"); /* write EGA regs */
- asm(" pop es"); /* restore segment register */
- }
- }
-
- void spectrum() /* create color spectrum palette */
- {
- int i;
- if (v_mode == 0x65) /* 1024x768x16 mode only */
- {
- ext_palette( 0, 0, 0, 0); /* black */
- ext_palette( 1, 63, 0, 0); /* red */
- ext_palette( 2, 63, 21, 0);
- ext_palette( 3, 63, 42, 0);
- ext_palette( 4, 63, 63, 0); /* yellow */
- ext_palette( 5, 42, 63, 0);
- ext_palette( 6, 21, 63, 0);
- ext_palette( 7, 0, 63, 0); /* green */
- ext_palette( 8, 0, 63, 21);
- ext_palette( 9, 0, 63, 42);
- ext_palette(10, 0, 63, 63); /* cyan */
- ext_palette(11, 0, 42, 63);
- ext_palette(12, 0, 21, 63);
- ext_palette(13, 0, 0, 63); /* blue */
- ext_palette(14, 21, 0, 63);
- ext_palette(15, 42, 0, 63); /* magenta */
- }
- else
- {
- if (v_color == 255) /* all 256 color modes */
- {
- vga_palette(0,0,0,0);
- for (i=1; i<=64; i++) { vga_palette(i,63,i-1,0); }
- for (i=65; i<=128; i++) { vga_palette(i,128-i,63,0); }
- for (i=129; i<=192; i++) { vga_palette(i,0,63,i-129); }
- for (i=193; i<=255; i++) { vga_palette(i,0,255-i,63); }
- }
- else
- { /* 16 color EGA modes except 1024x768 */
- set_palette(ega_palette);
- }
- }
- }
-
- void ext_palette(i,r,g,b) /* write to external palette registers */
- unsigned char i,r,g,b;
- {
- #define outp(p,v) dx = p; al = v; asm(dx,al," out dx,al")
- reg$eax unsigned char al,v;
- reg$edx unsigned short dx,p;
- outp(0x3C8, i);
- outp(0x3C9, r);
- outp(0x3C9, g);
- outp(0x3C9, b);
- outp(0x3C8, i<<4);
- outp(0x3C9, r);
- outp(0x3C9, g);
- outp(0x3C9, b);
- }
-
-
-